﻿namespace TestTool.GUI.Controls
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using System.Windows.Forms;
    using TestTool.GUI.Data;
    using TestTool.GUI.Utils;
    using TestTool.GUI.Views;
    using TestTool.Tests.Definitions.Data;
    using TestTool.Tests.Definitions.Enums;
    using TestTool.Tests.Definitions.Trace;

    public class TestsTree : UserControl, ITestTreeView
    {
        private bool _bProfileBeingApplied;
        private bool _bubbleCheck;
        private bool _certificationMode;
        private bool _certificationTestsSelected;
        private List<TreeNode> _colouredNodes;
        private Font _completedTestFont;
        private List<TreeNode> _groupNodes;
        private bool _inactive;
        private TreeNode _rightClickedNode;
        private List<string> _selectedGroups;
        private List<TestInfo> _selectedTests;
        private Dictionary<TestInfo, TreeNode> _testNodes;
        private ContextMenuStrip cmsTestsTree;
        private ToolStripMenuItem collapseAllToolStripMenuItem;
        private ToolStripMenuItem collapseCurrentToolStripMenuItem;
        private IContainer components;
        private ToolStripMenuItem expandAllToolStripMenuItem;
        private ToolStripMenuItem expandCurrentToolStripMenuItem;
        private ImageList ilTestIcons;
        private ToolStripSeparator toolStripMenuItem1;
        private TreeViewEx tvTestCases;

        public event TreeViewEventHandler AfterCheck;

        public event TreeViewEventHandler AfterSelect;

        public event TreeViewCancelEventHandler BeforeCheck;

        public event TreeViewCancelEventHandler BeforeSelect;

        public TestsTree()
        {
            this.InitializeComponent();
            this._selectedTests = new List<TestInfo>();
            this._selectedGroups = new List<string>();
            this._testNodes = new Dictionary<TestInfo, TreeNode>();
            this._colouredNodes = new List<TreeNode>();
            this._groupNodes = new List<TreeNode>();
            this._completedTestFont = new Font(this.tvTestCases.Font.FontFamily, this.tvTestCases.Font.Size, FontStyle.Bold);
        }

        public void ApplyProfileOptions(Profile profile)
        {
            this._bProfileBeingApplied = true;
            foreach (TestInfo info in this._testNodes.Keys)
            {
                this._testNodes[info].Checked = profile.TestCases.Contains(info.Order);
            }
            foreach (TreeNode node in this._groupNodes)
            {
                node.Checked = profile.TestGroups.Contains(node.Name);
            }
            this._bProfileBeingApplied = false;
        }

        private bool CanBeCollapsed(TreeNode node)
        {
            return (node.IsExpanded && (node.Nodes.Count > 0));
        }

        private bool CanBeExpanded(TreeNode node)
        {
            if (!node.IsExpanded && (node.Nodes.Count > 0))
            {
                return true;
            }
            foreach (TreeNode node2 in node.Nodes)
            {
                if (this.CanBeExpanded(node2))
                {
                    return true;
                }
            }
            return false;
        }

        private void CheckIfAllChildrenChecked(TreeNode node)
        {
            bool flag = true;
            foreach (TreeNode node2 in node.Nodes)
            {
                if (!node2.Checked)
                {
                    flag = false;
                    break;
                }
            }
            this._bubbleCheck = true;
            node.Checked = flag;
            this._bubbleCheck = false;
        }

        public void ClearTestResults()
        {
            foreach (TreeNode node in this._colouredNodes)
            {
                node.ForeColor = this.tvTestCases.ForeColor;
                node.NodeFont = this.tvTestCases.Font;
                node.ToolTipText = this.CreateTestTooltip((TestInfo)node.Tag, null);
            }
        }

        private void cmsTestsTree_Closing(object sender, ToolStripDropDownClosingEventArgs e)
        {
            if (this._rightClickedNode != null)
            {
                this._rightClickedNode.BackColor = this.tvTestCases.BackColor;
            }
            if ((e.CloseReason != ToolStripDropDownCloseReason.ItemClicked) && (e.CloseReason != ToolStripDropDownCloseReason.Keyboard))
            {
                this._rightClickedNode = null;
            }
        }

        private void cmsTestsTree_Opening(object sender, CancelEventArgs e)
        {
            TreeNode node = this._rightClickedNode;
            if (node == null)
            {
                this.expandCurrentToolStripMenuItem.Enabled = false;
                this.collapseCurrentToolStripMenuItem.Enabled = false;
            }
            else
            {
                this.expandCurrentToolStripMenuItem.Enabled = this.CanBeExpanded(node);
                this.collapseCurrentToolStripMenuItem.Enabled = this.CanBeCollapsed(node);
            }
            bool flag = false;
            bool flag2 = false;
            foreach (TreeNode node2 in this.tvTestCases.Nodes)
            {
                if (this.CanBeExpanded(node2))
                {
                    flag = true;
                    break;
                }
            }
            foreach (TreeNode node3 in this.tvTestCases.Nodes)
            {
                if (this.CanBeCollapsed(node3))
                {
                    flag2 = true;
                    break;
                }
            }
            this.expandAllToolStripMenuItem.Enabled = flag;
            this.collapseAllToolStripMenuItem.Enabled = flag2;
        }

        private void collapseAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.tvTestCases.CollapseAll();
            this._rightClickedNode = null;
        }

        private void collapseCurrentToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode node = this._rightClickedNode;
            if (node != null)
            {
                node.Collapse(false);
            }
            this._rightClickedNode = null;
        }

        private string CreateTestTooltip(TestInfo testInfo, TestResult testResult)
        {
            string name = testInfo.Name;
            string requirementString = testInfo.GetRequirementString();
            string str3 = "NOT PERFORMED";
            if (testResult != null)
            {
                if (testResult.Log.TestStatus == TestStatus.NotSupported)
                {
                    str3 = "NOT SUPPORTED";
                }
                else
                {
                    str3 = testResult.Log.TestStatus.ToString().ToUpper();
                }
            }
            return string.Format("{0}\r\n{1} \r\nState: {2}", name, requirementString, str3);
        }

        public void DisplayTests(IEnumerable<TestInfo> tests)
        {
            try
            {
                foreach (TestInfo info in from ti in tests
                                          orderby ti.Category, ti.Order
                                          select ti)
                {
                    TreeNode node = this.FindGroupNode(info.Group);
                    info.Name = string.Format("{0}-{1} {2}", info.Category, info.Id, info.Name);
                    TreeNode node2 = node.Nodes.Add(info.Name);
                    node2.ImageKey = this.FindImageKey(info);
                    node2.SelectedImageKey = node2.ImageKey;
                    node2.ToolTipText = this.CreateTestTooltip(info, null);
                    node2.Tag = info;
                    this._testNodes.Add(info, node2);
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
            }
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && (this.components != null))
            {
                this.components.Dispose();
            }
            base.Dispose(disposing);
        }

        private void expandAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.tvTestCases.ExpandAll();
            this._rightClickedNode = null;
        }

        private void expandCurrentToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode node = this._rightClickedNode;
            if (node != null)
            {
                node.ExpandAll();
            }
            this._rightClickedNode = null;
        }

        private TreeNode FindGroupNode(string path)
        {
            string[] strArray = path.Split(new char[] { '\\' });
            string text = strArray[0];
            TreeNode item = null;
            foreach (TreeNode node2 in this.tvTestCases.Nodes)
            {
                if (node2.Name == text)
                {
                    item = node2;
                    break;
                }
            }
            if (item == null)
            {
                item = this.tvTestCases.Nodes.Add(text);
                item.Name = text;
                item.ImageKey = "Group";
                item.SelectedImageKey = "Group";
                this._groupNodes.Add(item);
            }
            if (strArray.Length == 1)
            {
                return item;
            }
            TreeNode node3 = item;
            string str2 = text;
            for (int i = 1; i < strArray.Length; i++)
            {
                string str3 = strArray[i];
                TreeNode node4 = null;
                foreach (TreeNode node5 in node3.Nodes)
                {
                    if (node5.Name == str3)
                    {
                        node4 = node5;
                        break;
                    }
                }
                str2 = str2 + @"\" + str3;
                if (node4 == null)
                {
                    node4 = node3.Nodes.Add(str3);
                    node4.ImageKey = "Group";
                    node4.SelectedImageKey = "Group";
                    this._groupNodes.Add(node4);
                    node4.Name = str3;
                }
                node3 = node4;
            }
            return node3;
        }

        private string FindImageKey(TestInfo info)
        {
            switch (info.RequirementLevel)
            {
                case RequirementLevel.Must:
                    if (info.RequiredFeatures.Count != 0)
                    {
                        return "MUSTIF.ico";
                    }
                    return "MUST.ico";

                case RequirementLevel.Optional:
                    if (info.RequiredFeatures.Count != 0)
                    {
                        return "OPTIONALIF.ico";
                    }
                    return "OPTIONAL.ico";
            }
            return "None.ico";
        }

        public void HighlightActiveTest(TestInfo testInfo, bool scrollingEnabled)
        {
            if (this._testNodes.ContainsKey(testInfo))
            {
                TreeNode node = this._testNodes[testInfo];
                if (scrollingEnabled)
                {
                    this.tvTestCases.SelectedNode = node;
                }
                else
                {
                    node.BackColor = Color.LightGray;
                }
                node.EnsureVisible();
            }
        }

        public void HighlightCompletedTest(TestResult testResult)
        {
            if (this._testNodes.ContainsKey(testResult.TestInfo))
            {
                TreeNode item = this._testNodes[testResult.TestInfo];
                item.BackColor = this.tvTestCases.BackColor;
                Color foreColor = this.tvTestCases.ForeColor;
                switch (testResult.Log.TestStatus)
                {
                    case TestStatus.Failed:
                        foreColor = Color.Red;
                        break;

                    case TestStatus.Passed:
                        foreColor = Color.Green;
                        break;

                    case TestStatus.NotSupported:
                        foreColor = Color.Gray;
                        break;
                }
                if ((testResult.Log.TestStatus == TestStatus.Failed) || (testResult.Log.TestStatus == TestStatus.Passed))
                {
                    item.NodeFont = this._completedTestFont;
                    item.Text = item.Text;
                }
                item.ToolTipText = this.CreateTestTooltip(testResult.TestInfo, testResult);
                item.ForeColor = foreColor;
                this._colouredNodes.Add(item);
            }
        }

        private void InitializeComponent()
        {
            this.components = new Container();
            ComponentResourceManager manager = new ComponentResourceManager(typeof(TestsTree));
            this.cmsTestsTree = new ContextMenuStrip(this.components);
            this.expandCurrentToolStripMenuItem = new ToolStripMenuItem();
            this.collapseCurrentToolStripMenuItem = new ToolStripMenuItem();
            this.toolStripMenuItem1 = new ToolStripSeparator();
            this.expandAllToolStripMenuItem = new ToolStripMenuItem();
            this.collapseAllToolStripMenuItem = new ToolStripMenuItem();
            this.ilTestIcons = new ImageList(this.components);
            this.tvTestCases = new TreeViewEx();
            this.cmsTestsTree.SuspendLayout();
            base.SuspendLayout();
            this.cmsTestsTree.Items.AddRange(new ToolStripItem[] { this.expandCurrentToolStripMenuItem, this.collapseCurrentToolStripMenuItem, this.toolStripMenuItem1, this.expandAllToolStripMenuItem, this.collapseAllToolStripMenuItem });
            this.cmsTestsTree.Name = "cmsTestsTree";
            this.cmsTestsTree.Size = new Size(0xa3, 120);
            this.cmsTestsTree.Opening += new CancelEventHandler(this.cmsTestsTree_Opening);
            this.cmsTestsTree.Closing += new ToolStripDropDownClosingEventHandler(this.cmsTestsTree_Closing);
            this.expandCurrentToolStripMenuItem.Name = "expandCurrentToolStripMenuItem";
            this.expandCurrentToolStripMenuItem.Size = new Size(0xa2, 0x16);
            this.expandCurrentToolStripMenuItem.Text = "Expand Current";
            this.expandCurrentToolStripMenuItem.Click += new EventHandler(this.expandCurrentToolStripMenuItem_Click);
            this.collapseCurrentToolStripMenuItem.Name = "collapseCurrentToolStripMenuItem";
            this.collapseCurrentToolStripMenuItem.Size = new Size(0xa2, 0x16);
            this.collapseCurrentToolStripMenuItem.Text = "Collapse Current";
            this.collapseCurrentToolStripMenuItem.Click += new EventHandler(this.collapseCurrentToolStripMenuItem_Click);
            this.toolStripMenuItem1.Name = "toolStripMenuItem1";
            this.toolStripMenuItem1.Size = new Size(0x9f, 6);
            this.expandAllToolStripMenuItem.Name = "expandAllToolStripMenuItem";
            this.expandAllToolStripMenuItem.Size = new Size(0xa2, 0x16);
            this.expandAllToolStripMenuItem.Text = "Expand All";
            this.expandAllToolStripMenuItem.Click += new EventHandler(this.expandAllToolStripMenuItem_Click);
            this.collapseAllToolStripMenuItem.Name = "collapseAllToolStripMenuItem";
            this.collapseAllToolStripMenuItem.Size = new Size(0xa2, 0x16);
            this.collapseAllToolStripMenuItem.Text = "Collapse All";
            this.collapseAllToolStripMenuItem.Click += new EventHandler(this.collapseAllToolStripMenuItem_Click);
            this.ilTestIcons.ImageStream = (ImageListStreamer)manager.GetObject("ilTestIcons.ImageStream");
            this.ilTestIcons.TransparentColor = Color.Transparent;
            this.ilTestIcons.Images.SetKeyName(0, "None.ico");
            this.ilTestIcons.Images.SetKeyName(1, "Group");
            this.ilTestIcons.Images.SetKeyName(2, "OPTIONALIF.ico");
            this.ilTestIcons.Images.SetKeyName(3, "MUST.ico");
            this.ilTestIcons.Images.SetKeyName(4, "MUSTIF.ico");
            this.ilTestIcons.Images.SetKeyName(5, "OPTIONAL.ico");
            this.tvTestCases.CheckBoxes = true;
            this.tvTestCases.ContextMenuStrip = this.cmsTestsTree;
            this.tvTestCases.Dock = DockStyle.Fill;
            this.tvTestCases.FullRowSelect = true;
            this.tvTestCases.HideSelection = false;
            this.tvTestCases.ImageIndex = 0;
            this.tvTestCases.ImageList = this.ilTestIcons;
            this.tvTestCases.Indent = 0x13;
            this.tvTestCases.Location = new Point(0, 0);
            this.tvTestCases.Name = "tvTestCases";
            this.tvTestCases.SelectedImageIndex = 0;
            this.tvTestCases.ShowNodeToolTips = true;
            this.tvTestCases.Size = new Size(0x133, 0x18f);
            this.tvTestCases.TabIndex = 2;
            this.tvTestCases.NodeMouseDoubleClick += new TreeNodeMouseClickEventHandler(this.tvTestCases_NodeMouseDoubleClick);
            this.tvTestCases.AfterCheck += new TreeViewEventHandler(this.tvTestCases_AfterCheck);
            this.tvTestCases.MouseClick += new MouseEventHandler(this.tvTestCases_MouseClick);
            this.tvTestCases.AfterSelect += new TreeViewEventHandler(this.tvTestCases_AfterSelect);
            this.tvTestCases.NodeMouseClick += new TreeNodeMouseClickEventHandler(this.tvTestCases_NodeMouseClick);
            this.tvTestCases.BeforeCheck += new TreeViewCancelEventHandler(this.tvTestCases_BeforeCheck);
            this.tvTestCases.BeforeSelect += new TreeViewCancelEventHandler(this.tvTestCases_BeforeSelect);
            base.AutoScaleDimensions = new SizeF(6f, 13f);
            base.AutoScaleMode = AutoScaleMode.Font;
            base.Controls.Add(this.tvTestCases);
            base.Name = "TestsTree";
            base.Size = new Size(0x133, 0x18f);
            this.cmsTestsTree.ResumeLayout(false);
            base.ResumeLayout(false);
        }

        private void SelectAvailableChildTests(TreeNode node)
        {
            foreach (TreeNode node2 in node.Nodes)
            {
                if (node2.Tag != null)
                {
                    TestInfo tag = (TestInfo)node2.Tag;
                    node2.Checked = node.Checked;
                }
                else
                {
                    node2.Checked = node.Checked;
                    this.CheckIfAllChildrenChecked(node2);
                }
            }
        }

        private void SelectTestGroups()
        {
            List<TreeNode> list = new List<TreeNode>();
            foreach (TreeNode node in this.tvTestCases.Nodes)
            {
                if (node.Tag == null)
                {
                    list.Add(node);
                }
            }
            for (int i = 0; i < list.Count; i++)
            {
                foreach (TreeNode node2 in list[i].Nodes)
                {
                    if (node2.Tag == null)
                    {
                        list.Add(node2);
                    }
                }
            }
            for (int j = list.Count - 1; j >= 0; j--)
            {
                this.CheckIfAllChildrenChecked(list[j]);
            }
        }

        public void SelectTests(IEnumerable<TestInfo> testInfos)
        {
            base.BeginInvoke((Action)delegate
            {
                this._certificationTestsSelected = true;
                foreach (TestInfo info in this._testNodes.Keys)
                {
                    this._testNodes[info].Checked = testInfos.Contains<TestInfo>(info);
                }
                this.SelectTestGroups();
                this._certificationTestsSelected = false;
            });
        }

        public void SetInactive()
        {
            this._inactive = true;
        }

        private void TryCheckParent(TreeNode node)
        {
            for (TreeNode node2 = node; node2.Parent != null; node2 = node2.Parent)
            {
                this.CheckIfAllChildrenChecked(node2.Parent);
            }
        }

        private void tvTestCases_AfterCheck(object sender, TreeViewEventArgs e)
        {
            TreeNode node = e.Node;
            if (node.Tag != null)
            {
                TestInfo tag = (TestInfo)node.Tag;
                if (node.Checked)
                {
                    if (!this._selectedTests.Contains(tag))
                    {
                        this._selectedTests.Add(tag);
                    }
                }
                else
                {
                    this._selectedTests.Remove(tag);
                }
            }
            else
            {
                if (!this._bProfileBeingApplied && !this._bubbleCheck)
                {
                    if (this._certificationMode)
                    {
                        this.SelectAvailableChildTests(node);
                        this.CheckIfAllChildrenChecked(node);
                    }
                    else
                    {
                        foreach (TreeNode node2 in node.Nodes)
                        {
                            node2.Checked = node.Checked;
                        }
                    }
                }
                if (node.Checked)
                {
                    if (!this._selectedGroups.Contains(node.Name))
                    {
                        this._selectedGroups.Add(node.Name);
                    }
                }
                else
                {
                    this._selectedGroups.Remove(node.Name);
                }
            }
            if ((e.Action == TreeViewAction.ByKeyboard) || (e.Action == TreeViewAction.ByMouse))
            {
                if (node.Checked)
                {
                    this.TryCheckParent(node);
                }
                else
                {
                    this.UncheckParent(node);
                }
            }
            if (this.AfterCheck != null)
            {
                this.AfterCheck(this, e);
            }
        }

        private void tvTestCases_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (this.AfterSelect != null)
            {
                this.AfterSelect(this, e);
            }
        }

        private void tvTestCases_BeforeCheck(object sender, TreeViewCancelEventArgs e)
        {
            if (!this._certificationTestsSelected)
            {
                if (this.BeforeCheck != null)
                {
                    this.BeforeCheck(this, e);
                }
                if (!e.Cancel && this._certificationMode)
                {
                    e.Cancel = true;
                }
            }
        }

        private void tvTestCases_BeforeSelect(object sender, TreeViewCancelEventArgs e)
        {
            if (this.BeforeSelect != null)
            {
                this.BeforeSelect(this, e);
            }
        }

        private void tvTestCases_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                this._rightClickedNode = this.tvTestCases.GetNodeAt(e.X, e.Y);
                if (this._rightClickedNode != null)
                {
                    this._rightClickedNode.BackColor = Color.LightSkyBlue;
                }
            }
        }

        private void tvTestCases_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if ((((e.Button != MouseButtons.Right) && this._inactive) && ((e.Node == this.tvTestCases.SelectedNode) && this._inactive)) && (this.AfterSelect != null))
            {
                this._inactive = false;
                this.AfterSelect(this, new TreeViewEventArgs(e.Node));
            }
        }

        private void tvTestCases_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
        }

        private void UncheckParent(TreeNode node)
        {
            for (TreeNode node2 = node; node2.Parent != null; node2 = node2.Parent)
            {
                this._bubbleCheck = true;
                node2.Parent.Checked = false;
                this._bubbleCheck = false;
            }
        }

        public bool CertificationMode
        {
            get
            {
                return this._certificationMode;
            }
            set
            {
                this._certificationMode = value;
            }
        }

        public List<string> SelectedGroups
        {
            get
            {
                return this._selectedGroups;
            }
        }

        public TreeNode SelectedNode
        {
            get
            {
                return this.tvTestCases.SelectedNode;
            }
            set
            {
                this.tvTestCases.SelectedNode = value;
            }
        }

        public List<TestInfo> SelectedTests
        {
            get
            {
                return this._selectedTests;
            }
        }
    }
}

